
<script>
export default {
  props: {
    url: {
      type: String,
      default: 'rtmp://isxsports.com/dext/live14',
    },
    line: {
      type: String,
      default: '',
    },
    isCanLine: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      canvas: null,
      ctx: null,
      start: {
        x: null,
        y: null,
      },
      end: {
        x: null,
        y: null,
      },
      middle: {
        x: null,
        y: null,
      },
      moveToX: null,
      moveToY: null,
      drage: false,
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.canvas = document.getElementById('canvas')
      this.ctx = this.canvas.getContext('2d')
      this.canvas.width = this.canvas.clientWidth || 660
      this.canvas.height = this.canvas.clientHeight || 400
      if (this.line) {
        let port = JSON.parse(this.line)
        this.start.x = port[0].x * this.canvas.width
        this.start.y = port[0].y * this.canvas.height
        this.end.x = port[1].x * this.canvas.width
        this.end.y = port[1].y * this.canvas.height
        this.middle.x = (this.start.x + this.end.x) / 2
        this.middle.y = (this.start.y + this.end.y) / 2
        this.mousemoveEvent()
        this.drawArrowCompute()
      }
      if (this.isCanLine) {
        this.canvas.addEventListener('click', this.mousedownEvent.bind(this))
      }
    })
  },
  methods: {
    reset() {
      this.start.x = this.start.y = this.end.x = this.end.y = this.middle.x = this.middle.y = null
      this.drage = false
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
      this.canvas.removeEventListener('mousemove', this.mousemoveEvent, false)
      this.canvas.removeEventListener(
        'mousemove',
        this.mousemoveEventCanvas,
        false
      )
    },
    mousedownEvent(e) {
      if (!this.start.x) {
        this.start.x = e.offsetX
        this.start.y = e.offsetY
        this.canvas.addEventListener('mousemove', this.mousemoveEvent, false)
      } else if (!this.end.x) {
        this.end.x = e.offsetX
        this.end.y = e.offsetY
        this.middle.x = (this.start.x + this.end.x) / 2
        this.middle.y = (this.start.y + this.end.y) / 2
        this.drawArrowCompute()
        this.canvas.removeEventListener('mousemove', this.mousemoveEvent, false)
      } else {
        if (this.drage) {
          this.drage = false
          this.canvas.removeEventListener(
            'mousemove',
            this.mousemoveEventCanvas,
            false
          )
        } else {
          this.drage = true
          this.canvas.addEventListener(
            'mousemove',
            this.mousemoveEventCanvas,
            false
          )
        }
      }
    },
    drawArrowCompute() {
      let baseOffset = 40
      let x1 = this.end.x,
        y1 = -this.end.y,
        x2 = this.start.x,
        y2 = -this.start.y
      let centerx = (x1 + x2) / 2
      let centery = -(y1 + y2) / 2
      let ofsetx = baseOffset
      let ofsety = baseOffset
      let k = 0
      let b = (y1 + y2) / 2 + ((x1 - x2) * (x1 + x2)) / (2 * (y1 - y2))
      let endCenterX = 0,
        endCentery = 0
      if (y1 == y2) {
        if (x1 < x2) {
          ofsety = -baseOffset
        }
        endCenterX = centerx
        endCentery = centery + ofsety
      } else {
        k = (x2 - x1) / (y1 - y2) //斜率
        if ((k > 0 && x1 > x2) || (k < 0 && x1 < x2)) {
          ofsetx = -baseOffset
        }
        if (-1 < k && k < 1) {
          endCenterX = (x1 + x2) / 2 + ofsetx
          endCentery = -(k * endCenterX + b)
        } else {
          if ((k > 0 && y1 > y2) || (k < 0 && y1 < y2)) {
            ofsety = -baseOffset
          }
          endCentery = (y1 + y2) / 2 - ofsety
          endCenterX = (endCentery - b) / k
          endCentery = -endCentery
        }
      }
      this.drawArrow(
        this.ctx,
        centerx,
        centery,
        endCenterX,
        endCentery,
        15,
        20,
        2,
        '#f36'
      )
    },
    mousemoveEventCanvas(e) {
      let ofsetx = e.offsetX - this.middle.x
      let ofsety = e.offsetY - this.middle.y
      let endx, endy, startx, starty
      endx = this.end.x + ofsetx
      endy = this.end.y + ofsety
      startx = this.start.x + ofsetx
      starty = this.start.y + ofsety
      if (
        endx <= 0 ||
        endy <= 0 ||
        startx <= 0 ||
        starty <= 0 ||
        endx >= this.canvas.width ||
        startx >= this.canvas.width ||
        endy >= this.canvas.height ||
        starty >= this.canvas.height
      ) {
        return false
      }
      this.middle.x = e.offsetX
      this.middle.y = e.offsetY
      this.end.x = endx
      this.end.y = endy
      this.start.x = startx
      this.start.y = starty
      this.mousemoveEvent()
      this.drawArrowCompute()
    },
    mousemoveEvent(e) {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
      this.ctx.strokeStyle = '#fff'
      this.ctx.lineWidth = 2
      this.ctx.beginPath()
      this.ctx.moveTo(this.start.x, this.start.y)
      this.ctx.lineTo(e ? e.offsetX : this.end.x, e ? e.offsetY : this.end.y)
      this.ctx.stroke()
      this.ctx.closePath()
    },
    /**
     * ctx：Canvas绘图环境，fromX, fromY：起点坐标（也可以换成 p1 ，只不过它是一个数组）
     * toX, toY：终点坐标 (也可以换成 p2 ，只不过它是一个数组)
     * theta：三角斜边一直线夹角，headlen：三角斜边长度
     * width：箭头线宽度，color：箭头颜色
     */
    drawArrow(ctx, fromX, fromY, toX, toY, theta, headlen, width, color) {
      var theta = theta || 30,
        headlen = headlen || 10,
        width = width || 1,
        color = color || '#000',
        angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI,
        angle1 = ((angle + theta) * Math.PI) / 180,
        angle2 = ((angle - theta) * Math.PI) / 180,
        topX = headlen * Math.cos(angle1),
        topY = headlen * Math.sin(angle1),
        botX = headlen * Math.cos(angle2),
        botY = headlen * Math.sin(angle2)
      ctx.save()
      ctx.beginPath()
      var arrowX, arrowY
      ctx.moveTo(fromX, fromY)
      ctx.lineTo(toX, toY)
      arrowX = toX + topX
      arrowY = toY + topY
      ctx.moveTo(arrowX, arrowY)
      ctx.lineTo(toX, toY)
      arrowX = toX + botX
      arrowY = toY + botY
      ctx.lineTo(arrowX, arrowY)
      ctx.strokeStyle = color
      ctx.lineWidth = width
      ctx.stroke()
      ctx.restore()
    },
  },
  destroyed() {
    this.reset()
  },
}
</script>

<template lang="pug">
.canvas
  canvas(id="canvas" :style="{cursor:(drage?'all-scroll':'')}")
  el-button.btn(type="primary" v-if="start.x!=null&&isCanLine" icon="el-icon-edit" size="small" @click="reset") 重绘
</template>

<style lang="stylus" scoped>
.canvas
  height 100%
  width 100%
  canvas
    height 100%
    width 100%
  .btn
    position absolute
    top 0
    right 0
</style>
